package com.yuluke.ylsaudiorecorder.play;

import android.content.Context;
import android.content.Intent;
import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.util.Log;

import com.yuluke.ylsaudiorecorder.record.RecordConfig;

import java.io.File;
import java.io.FileInputStream;

public class YlsPlayer {

    private static final String TAG = "YlsRec_YlsPlayer";
    private final Context mContext;
    private OnProgressListener mProgressListener;

    public YlsPlayer(Context context) {
        mContext = context;
    }

    public void start(String path) {
        new PlayThread(path, getSessionId()).start();
    }

    public void setProgressListener(OnProgressListener mProgressListener) {
        this.mProgressListener = mProgressListener;
    }

    private int getSessionId() {
        AudioManager audioManager = mContext.getSystemService(AudioManager.class);
        return audioManager.generateAudioSessionId();
    }

    class PlayThread extends Thread {

        private final String mFileAbsPath;
        private final AudioTrack mAudioTrack;
        private final int mMinBufferSize;

        public PlayThread(String path, int sessionId) {
            mFileAbsPath = path;

            AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
            attrBuilder.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH);
            attrBuilder.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION);

            AudioFormat.Builder afBuilder = new AudioFormat.Builder();
            afBuilder.setChannelMask(AudioFormat.CHANNEL_OUT_MONO);
            afBuilder.setEncoding(AudioFormat.ENCODING_PCM_16BIT);

            RecordConfig.BaseConfig cfg = RecordConfig.getInstance().getSimpleConfig();
            mMinBufferSize = AudioTrack.getMinBufferSize(/*cfg.getSampleRate()*/16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
            Log.i(TAG, "PlayThread constructor, file path:" + path
                    + ", sessionId:" + sessionId
                    + ", mMinBufferSize:" + mMinBufferSize);
            mAudioTrack = new AudioTrack(attrBuilder.build(), afBuilder.build(), mMinBufferSize, AudioTrack.MODE_STREAM, sessionId);
        }

        @Override
        public void run() {
            File file = new File(mFileAbsPath);
            if (!file.exists()) {
                Log.i(TAG, "PlayThread, file not exist, return.");
                return;
            }
            if (!file.canRead()) {
                Log.i(TAG, "PlayThread, file can not read, return.");
                if (!file.setReadable(true)) {
                    Log.i(TAG, "PlayThread, file can not read after setReadable, return.");
                }
                return;
            }

            try {
                mAudioTrack.play();
                FileInputStream fis = new FileInputStream(file);
                int total = fis.available();
                int progress = 0;
                byte[] buffer = new byte[mMinBufferSize];
                while(true) {
                    int len = fis.read(buffer, 0 , mMinBufferSize);
                    if (len == -1) {
                        break;
                    }
                    progress += len;
                    notifyProgress(total, progress);
                    Log.i(TAG, "PlayThread, write len:" + len);
                    mAudioTrack.write(buffer, 0, len);
                }
            } catch (Exception e) {
                Log.i(TAG, "Play Thread error", e);
                throw new RuntimeException(e);
            }
            mAudioTrack.stop();
            Log.i(TAG, "PlayThread, end");
        }
    }

    private void notifyProgress(int total, int progress) {
        if (mProgressListener != null) mProgressListener.onProgress(total, progress);
    }

    interface OnProgressListener {
        void onProgress(int total, int progress);
    }
}